//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Resource Application Block
//===============================================================================

using System;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability;
using EntLibContrib.Resource;
using EntLibContrib.Resource.Providers;
using EntLibContrib.Resource.Configuration;
using EntLibContrib.Resource.Configuration.Manageability;
using EntLibContrib.Resource.Configuration.Manageability.Tests.Adm;
using EntLibContrib.Resource.Configuration.Manageability.Tests.Mocks;

#if !NUNIT
using Microsoft.VisualStudio.TestTools.UnitTesting;
#else
using NUnit.Framework;
using TestClass = NUnit.Framework.TestFixtureAttribute;
using TestInitialize = NUnit.Framework.SetUpAttribute;
using TestCleanup = NUnit.Framework.TearDownAttribute;
using TestMethod = NUnit.Framework.TestAttribute;
#endif

namespace EntLibContrib.Resource.Configuration.Manageability.Tests
{
	[TestClass]
	public class ResourceManagerSettingsManageabilityProviderFixture
	{
		private ConfigurationSectionManageabilityProviderWrapper provider;
		private MockRegistryKey machineKey;
		private MockRegistryKey userKey;
		private IList<ConfigurationSetting> wmiSettings;
		private ResourceManagerSettings section;
		private DictionaryConfigurationSource configurationSource;
		private static ResourceManager internalResources = InternalResourceFactory.GetResourceManager();

		[TestInitialize]
		public void SetUp()
		{
			provider = new ConfigurationSectionManageabilityProviderWrapper(
				new ResourceManagerSettingsManageabilityProvider(new Dictionary<Type, ConfigurationElementManageabilityProvider>(0)));
			machineKey = new MockRegistryKey(true);
			userKey = new MockRegistryKey(true);
			wmiSettings = new List<ConfigurationSetting>();
			section = new ResourceManagerSettings();
			configurationSource = new DictionaryConfigurationSource();
			configurationSource.Add(ResourceManagerSettings.SectionName, section);
		}

		[TestMethod]
		public void ManageabilityProviderIsProperlyRegistered()
		{
			ConfigurationSectionManageabilityProviderAttribute selectedAttribute = null;

			Assembly assembly = typeof(ResourceManagerSettingsManageabilityProvider).Assembly;
			foreach (ConfigurationSectionManageabilityProviderAttribute providerAttribute
				in assembly.GetCustomAttributes(typeof(ConfigurationSectionManageabilityProviderAttribute), false))
			{
				if (providerAttribute.SectionName.Equals(ResourceManagerSettings.SectionName))
				{
					selectedAttribute = providerAttribute;
					break;
				}
			}

			Assert.IsNotNull(selectedAttribute);
			Assert.AreSame(typeof(ResourceManagerSettingsManageabilityProvider), selectedAttribute.ManageabilityProviderType);
		}

		[TestMethod]
		[ExpectedException(typeof(ArgumentException))]
		public void ProviderThrowsWithConfigurationObjectOfWrongType()
		{
			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(new TestsConfigurationSection(), true, machineKey, userKey, true, wmiSettings);
		}

		[TestMethod]
		public void SectionIsNotModifiedIfThereAreNoPolicyOverrides()
		{
			section.DefaultResourceManager = "default";

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(section, true, machineKey, userKey, true, wmiSettings);

			Assert.AreEqual("default", section.DefaultResourceManager);
		}

		[TestMethod]
		public void NoExceptionsAreThrownIfMachineKeyIsNull()
		{
			section.DefaultResourceManager = "default";

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(section, true, null, userKey, true, wmiSettings);
		}

		[TestMethod]
		public void NoExceptionsAreThrownIfUserKeyIsNull()
		{
			section.DefaultResourceManager = "default";

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(section, true, machineKey, null, true, wmiSettings);
		}

		[TestMethod]
		public void SectionPropertiesAreOverridenFromMachineKey()
		{
			section.DefaultResourceManager = "default";

			machineKey.AddBooleanValue(ResourceManagerSettingsManageabilityProvider.PolicyValueName, true);
			machineKey.AddStringValue(ResourceManagerSettingsManageabilityProvider.DefaultResourceManagerPropertyName, "machineOverridenDefault");

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(section, true, machineKey, userKey, true, wmiSettings);

			Assert.AreEqual("machineOverridenDefault", section.DefaultResourceManager);
		}

		[TestMethod]
		public void SectionPropertiesAreOverridenFromUserKey()
		{
			section.DefaultResourceManager = "default";

			userKey.AddBooleanValue(ResourceManagerSettingsManageabilityProvider.PolicyValueName, true);
			userKey.AddStringValue(ResourceManagerSettingsManageabilityProvider.DefaultResourceManagerPropertyName, "userOverridenDefault");

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(section, true, machineKey, userKey, true, wmiSettings);

			Assert.AreEqual("userOverridenDefault", section.DefaultResourceManager);
		}

		[TestMethod]
		public void SectionPropertiesAreNotOverridenIfThereArePolicyOverridesButGroupPoliciesAreDisabled()
		{
			section.DefaultResourceManager = "default";

			machineKey.AddBooleanValue(ResourceManagerSettingsManageabilityProvider.PolicyValueName, true);
			machineKey.AddStringValue(ResourceManagerSettingsManageabilityProvider.DefaultResourceManagerPropertyName, "machineOverridenDefault");

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(section, false, machineKey, userKey, true, wmiSettings);

			Assert.AreEqual("default", section.DefaultResourceManager);
		}

		[TestMethod]
		public void ResourceManagerIsNotOverridenIfThereAreNoPolicyOverrides()
		{
			ResourceManagerData data1 = new ResourceManagerData();
			data1.Name = "resource manager 1";
			data1.ResourceProvider = "resource provider";
			section.ResourceManagers.Add(data1);

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(section, false, machineKey, userKey, true, wmiSettings);

			Assert.AreEqual("resource provider", data1.ResourceProvider);
		}

		[TestMethod]
		public void ResourceManagerIsOverridenIfThereAreMachinePolicyOverrides()
		{
			ResourceManagerData data1 = new ResourceManagerData();
			data1.Name = "resource manager 1";
			data1.ResourceProvider = "resource provider";
			section.ResourceManagers.Add(data1);

			MockRegistryKey machineResourceManagersKey = new MockRegistryKey(false);
			machineKey.AddSubKey(ResourceManagerSettingsManageabilityProvider.ResourceManagersKeyName, machineResourceManagersKey);
			MockRegistryKey machineResourceManager1Key = new MockRegistryKey(false);
			machineResourceManagersKey.AddSubKey(data1.Name, machineResourceManager1Key);

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(section, true, machineKey, userKey, true, wmiSettings);

			Assert.AreEqual("resource provider", data1.ResourceProvider);

			Assert.IsTrue(MockRegistryKey.CheckAllClosed(machineResourceManagersKey, machineResourceManager1Key));
		}

		[TestMethod]
		public void ResourceManagerIsOverridenIfThereAreUserPolicyOverrides()
		{
			ResourceManagerData data1 = new ResourceManagerData();
			data1.Name = "resource manager 1";
			data1.ResourceProvider = "resource provider";
			section.ResourceManagers.Add(data1);

			MockRegistryKey userResourceManagersKey = new MockRegistryKey(false);
			userKey.AddSubKey(ResourceManagerSettingsManageabilityProvider.ResourceManagersKeyName, userResourceManagersKey);
			MockRegistryKey userResourceManager1Key = new MockRegistryKey(false);
			userResourceManagersKey.AddSubKey(data1.Name, userResourceManager1Key);

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(section, true, machineKey, userKey, true, wmiSettings);

			Assert.AreEqual("resource provider", data1.ResourceProvider);

			Assert.IsTrue(MockRegistryKey.CheckAllClosed(userResourceManagersKey, userResourceManager1Key));
		}

		[TestMethod]
		public void ResourceManagerIsNotOverridenIfThereArePolicyOverridesForDifferentName()
		{
			ResourceManagerData data1 = new ResourceManagerData();
			data1.Name = "resource manager 1";
			data1.ResourceProvider = "resource provider";
			section.ResourceManagers.Add(data1);

			MockRegistryKey machineResourceManagersKey = new MockRegistryKey(false);
			machineKey.AddSubKey(ResourceManagerSettingsManageabilityProvider.ResourceManagersKeyName, machineResourceManagersKey);
			MockRegistryKey machineResourceManager1Key = new MockRegistryKey(false);
			machineResourceManagersKey.AddSubKey("resource manager 2", machineResourceManager1Key);

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(section, true, machineKey, userKey, true, wmiSettings);

			Assert.AreEqual("resource provider", data1.ResourceProvider);

			Assert.IsTrue(MockRegistryKey.CheckAllClosed(machineResourceManagersKey, machineResourceManager1Key));
		}

		[TestMethod]
		public void ResourceManagerWithDisabledPolicyIsRemoved()
		{
			ResourceManagerData data1 = new ResourceManagerData();
			data1.Name = "resource manager 1";
			section.ResourceManagers.Add(data1);
			ResourceManagerData data2 = new ResourceManagerData();
			data2.Name = "resource manager 2";
			section.ResourceManagers.Add(data2);

			MockRegistryKey machineResourceManagersKey = new MockRegistryKey(false);
			machineKey.AddSubKey(ResourceManagerSettingsManageabilityProvider.ResourceManagersKeyName, machineResourceManagersKey);
			MockRegistryKey machineResourceManager1Key = new MockRegistryKey(false);
			machineResourceManagersKey.AddSubKey("resource manager 1", machineResourceManager1Key);
			machineResourceManager1Key.AddBooleanValue(AdmContentBuilder.AvailableValueName, false);

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(section, true, machineKey, userKey, true, wmiSettings);

			Assert.AreEqual(1, section.ResourceManagers.Count);
			Assert.IsNotNull(section.ResourceManagers.Get("resource manager 2"));

			Assert.IsTrue(MockRegistryKey.CheckAllClosed(machineResourceManagersKey, machineResourceManager1Key));
		}

		[TestMethod]
		public void ResourceManagerWithDisabledPolicyIsNotRemovedIfGroupPoliciesAreDisabled()
		{
			ResourceManagerData data1 = new ResourceManagerData();
			data1.Name = "resource manager 1";
			section.ResourceManagers.Add(data1);
			ResourceManagerData data2 = new ResourceManagerData();
			data2.Name = "resource manager 2";
			section.ResourceManagers.Add(data2);

			MockRegistryKey machineResourceManagersKey = new MockRegistryKey(false);
			machineKey.AddSubKey(ResourceManagerSettingsManageabilityProvider.ResourceManagersKeyName, machineResourceManagersKey);
			MockRegistryKey machineResourceManager1Key = new MockRegistryKey(false);
			machineResourceManagersKey.AddSubKey("resource manager 1", machineResourceManager1Key);
			machineResourceManager1Key.AddBooleanValue(AdmContentBuilder.AvailableValueName, false);

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(section, false, machineKey, userKey, true, wmiSettings);

			Assert.AreEqual(2, section.ResourceManagers.Count);
			Assert.IsNotNull(section.ResourceManagers.Get("resource manager 1"));
			Assert.IsNotNull(section.ResourceManagers.Get("resource manager 2"));

			Assert.IsTrue(MockRegistryKey.CheckAllClosed(machineResourceManagersKey, machineResourceManager1Key));
		}

		//[TestMethod]
		//public void RegisteredResourceProviderDataProviderIsCalledWithNoOverrides()
		//{
		//  MockConfigurationElementManageabilityProvider registeredProvider
		//    = new MockConfigurationElementManageabilityProvider();
		//  Dictionary<Type, ConfigurationElementManageabilityProvider> subProviders
		//    = new Dictionary<Type, ConfigurationElementManageabilityProvider>();
		//  subProviders.Add(typeof(ResourceProviderData), registeredProvider);
		//  provider = new ConfigurationSectionManageabilityProviderWrapper(
		//    new ResourceManagerSettingsManageabilityProvider(subProviders));

		//  ResourceProviderData data = new ResourceProviderData("provider1", typeof(AssemblyResourceProvider));
		//  section.ResourceProviders.Add(data);

		//  provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(section, true, machineKey, userKey, true, wmiSettings);

		//  Assert.IsTrue(registeredProvider.called);
		//  Assert.AreSame(data, registeredProvider.LastConfigurationObject);
		//  Assert.AreEqual(null, registeredProvider.machineKey);
		//  Assert.AreEqual(null, registeredProvider.userKey);
		//}

		//[TestMethod]
		//public void RegisteredResourceProviderDataProviderIsCalledWithCorrectOverrides()
		//{
		//  MockConfigurationElementManageabilityProvider registeredProvider
		//    = new MockConfigurationElementManageabilityProvider();
		//  Dictionary<Type, ConfigurationElementManageabilityProvider> subProviders
		//    = new Dictionary<Type, ConfigurationElementManageabilityProvider>();
		//  subProviders.Add(typeof(ResourceProviderData), registeredProvider);
		//  provider = new ConfigurationSectionManageabilityProviderWrapper(
		//    new ResourceManagerSettingsManageabilityProvider(subProviders));

		//  ResourceProviderData data = new ResourceProviderData("provider1", typeof(AssemblyResourceProvider));
		//  section.ResourceProviders.Add(data);

		//  MockRegistryKey machineStoresKey = new MockRegistryKey(false);
		//  machineKey.AddSubKey(ResourceManagerSettingsManageabilityProvider.ResourceProvidersKeyName, machineStoresKey);
		//  MockRegistryKey machineStoreKey = new MockRegistryKey(false);
		//  machineStoresKey.AddSubKey("provider1", machineStoreKey);
		//  MockRegistryKey machineOtherStoreKey = new MockRegistryKey(false);
		//  machineStoresKey.AddSubKey("provider2", machineOtherStoreKey);

		//  MockRegistryKey userStoresKey = new MockRegistryKey(false);
		//  userKey.AddSubKey(ResourceManagerSettingsManageabilityProvider.ResourceProvidersKeyName, userStoresKey);
		//  MockRegistryKey userStoreKey = new MockRegistryKey(false);
		//  userStoresKey.AddSubKey("provider1", userStoreKey);
		//  MockRegistryKey userOtherStoreKey = new MockRegistryKey(false);
		//  userStoresKey.AddSubKey("provider2", userOtherStoreKey);

		//  provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(section, true, machineKey, userKey, true, wmiSettings);

		//  Assert.IsTrue(registeredProvider.called);
		//  Assert.AreSame(data, registeredProvider.LastConfigurationObject);
		//  Assert.AreEqual(machineStoreKey, registeredProvider.machineKey);
		//  Assert.AreEqual(userStoreKey, registeredProvider.userKey);

		//  Assert.IsTrue(MockRegistryKey.CheckAllClosed(machineStoresKey, machineStoreKey, machineOtherStoreKey, userStoresKey, userStoreKey, userOtherStoreKey));
		//}

		[TestMethod]
		public void WmiSettingsAreNotGeneratedIfWmiIsDisabled()
		{
			section.DefaultResourceManager = "default";

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(section, false, machineKey, userKey, false, wmiSettings);

			Assert.AreEqual(0, wmiSettings.Count);
		}

		[TestMethod]
		public void WmiSettingsAreGeneratedIfWmiIsEnabled()
		{
			section.DefaultResourceManager = "default";

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(section, false, machineKey, userKey, true, wmiSettings);

			Assert.AreEqual(1, wmiSettings.Count);
			Assert.AreSame(typeof(ResourceBlockSetting), wmiSettings[0].GetType());
			Assert.AreEqual("default", ((ResourceBlockSetting)wmiSettings[0]).DefaultResourceManager);
		}

		[TestMethod]
		public void WmiSettingsForResourceManagerAreGeneratedIfWmiIsEnabled()
		{
			section.DefaultResourceManager = "default";
			ResourceManagerData data1 = new ResourceManagerData();
			data1.Name = "resource manager 1";
			data1.ResourceProvider = "resource provider";
			section.ResourceManagers.Add(data1);

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(section, false, machineKey, userKey, true, wmiSettings);

			Assert.AreEqual(2, wmiSettings.Count);
			Assert.AreSame(typeof(ResourceBlockSetting), wmiSettings[0].GetType());
			Assert.AreEqual("default", ((ResourceBlockSetting)wmiSettings[0]).DefaultResourceManager);
			Assert.AreSame(typeof(ResourceManagerSetting), wmiSettings[1].GetType());
			Assert.AreEqual("resource manager 1", ((ResourceManagerSetting)wmiSettings[1]).Name);
			Assert.AreEqual("resource provider", ((ResourceManagerSetting)wmiSettings[1]).ResourceProvider);
		}

		[TestMethod]
		public void WmiSettingsAreGeneratedWithPolicyOverridesIfWmiIsEnabled()
		{
			section.DefaultResourceManager = "default";

			machineKey.AddBooleanValue(ResourceManagerSettingsManageabilityProvider.PolicyValueName, true);
			machineKey.AddStringValue(ResourceManagerSettingsManageabilityProvider.DefaultResourceManagerPropertyName, "machineOverridenDefault");

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(section, true, machineKey, userKey, true, wmiSettings);

			Assert.AreEqual(1, wmiSettings.Count);
			Assert.AreSame(typeof(ResourceBlockSetting), wmiSettings[0].GetType());
			Assert.AreEqual("machineOverridenDefault", ((ResourceBlockSetting)wmiSettings[0]).DefaultResourceManager);
		}

		//[TestMethod]
		//public void ManageabilityProviderGeneratesProperAdmContent()
		//{
		//  DictionaryConfigurationSource configurationSource = new DictionaryConfigurationSource();
		//  configurationSource.Add(ResourceManagerSettings.SectionName, section);

		//  AssemblyResourceProviderData provider1, provider2;
		//  ResourceManagerData manager1, manager2;
		//  section.ResourceProviders.Add(provider1 = new AssemblyResourceProviderData("provider1", "assembly1", "base1"));
		//  section.ResourceManagers.Add(manager1 = new ResourceManagerData("manager1", "provider1"));
		//  section.ResourceProviders.Add(provider2 = new AssemblyResourceProviderData("provider2", "assembly2", "base2"));
		//  section.ResourceManagers.Add(manager2 = new ResourceManagerData("manager2", "provider2"));

		//  MockConfigurationElementManageabilityProvider subProvider = new MockConfigurationElementManageabilityProvider();
		//  Dictionary<Type, ConfigurationElementManageabilityProvider> subProviders
		//    = new Dictionary<Type, ConfigurationElementManageabilityProvider>();
		//  subProviders.Add(typeof(AssemblyResourceProviderData), subProvider);
		//  provider = new ConfigurationSectionManageabilityProviderWrapper(new ResourceManagerSettingsManageabilityProvider(subProviders));

		//  MockAdmContentBuilder contentBuilder = new MockAdmContentBuilder();

		//  provider.InvokeAddAdministrativeTemplateDirectives(contentBuilder, section, configurationSource, "TestApp");

		//  Assert.AreEqual(2, subProvider.configurationObjects.Count);
		//  Assert.AreSame(provider1, subProvider.configurationObjects[0]);
		//  Assert.AreSame(provider2, subProvider.configurationObjects[1]);
		//  MockAdmContent content = contentBuilder.GetMockContent();
		//  IEnumerator<AdmCategory> categoriesEnumerator = content.Categories.GetEnumerator();
		//  Assert.IsTrue(categoriesEnumerator.MoveNext());
		//  Assert.AreEqual(publicResources["ResourceSectionCategoryName"], categoriesEnumerator.Current.Name);
		//  IEnumerator<AdmCategory> subCategoriesEnumerator = categoriesEnumerator.Current.Categories.GetEnumerator();
		//  Assert.IsTrue(subCategoriesEnumerator.MoveNext());
		//  Assert.AreEqual(publicResources["ResourceManagersCategoryName"], subCategoriesEnumerator.Current.Name);
		//  IEnumerator<AdmPolicy> resourceManagerPoliciesEnumerator = subCategoriesEnumerator.Current.Policies.GetEnumerator();
		//  Assert.IsTrue(resourceManagerPoliciesEnumerator.MoveNext());
		//  Assert.AreEqual(publicResources["ResourceManagerPolicyNameTemplate", manager1.Name], resourceManagerPoliciesEnumerator.Current.Name);
		//  Assert.IsTrue(resourceManagerPoliciesEnumerator.MoveNext());
		//  Assert.AreEqual(publicResources["ResourceManagerPolicyNameTemplate", manager2.Name], resourceManagerPoliciesEnumerator.Current.Name);
		//  Assert.IsFalse(resourceManagerPoliciesEnumerator.MoveNext());
		//  Assert.IsFalse(subCategoriesEnumerator.MoveNext());
		//  IEnumerator<AdmPolicy> sectionPoliciesEnumerator = categoriesEnumerator.Current.Policies.GetEnumerator();
		//  Assert.IsTrue(sectionPoliciesEnumerator.MoveNext());
		//  Assert.AreEqual(publicResources["ResourceManagerSettingsPolicyName"], sectionPoliciesEnumerator.Current.Name);
		//  Assert.IsFalse(sectionPoliciesEnumerator.MoveNext());
		//  Assert.IsFalse(categoriesEnumerator.MoveNext());
		//}
	}
}
